package edu.gmu.atelier;

/**
 * Solves for x* for the equation Ax=b where Ax*=b* is the "closest"
 * to b in the span(A) (||b - Ax*|| &lt= ||b - Ax|| for all x in R^N).
 * <p>
 * The solver uses the factorization A = QR to form Rx*=Q^Tb and then
 * solves for x* using back substitution with upper triangular R.
 * <p>
 * It is assumed that the matrix A has linearly independent vectors
 * so that there is a unique x*.
 * 
 * @author James H. Pope
 */
public class LSQRSolver implements Solver
{
    private Matrix a    = null;
    
    private Matrix qt    = null;
    private Matrix r     = null;
    
    public LSQRSolver( Matrix a )
    {
        this.a = a;
        
        // Decompose - remember matrices/vectors needed for solving
        QRFactor qrf = new QRGramSchmidtFactor(a);
        this.r = qrf.getR();
        this.qt = qrf.getQ().transpose();
    }
    
    public Matrix getA()
    {
        return this.a;
    }
    
    public Matrix getR()
    {
        return this.r;
    }
    
    public Matrix getQT()
    {
        return this.qt;
    }
    
    //------------------------------------------------------------------------//
    // Interface methods
    //------------------------------------------------------------------------//
    public Vector solve( Vector b )
    {
        Vector qtb   = b.mult(qt);
        Vector xstar = LUFactor.backSubstitution(r, qtb);
        return xstar;
    }
    
}
